package com.xiaomaoguai.fcp.pre.kepler.router.handler.handlercontext;

import java.util.Map;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

import com.xiaomaoguai.fcp.pre.kepler.router.buf.Buf;
import com.xiaomaoguai.fcp.pre.kepler.router.async.delay.RetryInfo;
import com.xiaomaoguai.fcp.pre.kepler.router.router.RouterPipeline;

/**
 * handler 容器
 *
 * @author DH
 */
public class DefaultHandlerContext<I> extends AbstractHandlerContext<I> implements Delayed {

	private RouterPipeline<?, ?> router;

	private RetryInfo retryInfo;

	public RetryInfo retry(Map<String, String> retryParams) {
		if (retryInfo != null) {
			retryInfo.nextTime();
			return retryInfo;
		}
		retryInfo = new RetryInfo().interval(retryParams.get("interval"))
				.maxretryTimes(retryParams.get("maxretryTimes"));
		retryInfo.retryStrategy(retryParams.get("retryStrategy"));
		return retryInfo;

	}

	public DefaultHandlerContext(RouterPipeline<?, ?> router) {
		this.router = router;
	}

	@Override
	public Buf getBuf() {
		return router.getBuf();
	}

	@Override
	public RouterPipeline<?, ?> getRouter() {
		return router;
	}

	@Override
	public int compareTo(Delayed o) {
		if (o instanceof DefaultHandlerContext) {
			RetryInfo retryInfo = DefaultHandlerContext.class.cast(o).getRetryInfo();
			return this.retryInfo.compareTo(retryInfo);
		}
		return 0;
	}

	@Override
	public long getDelay(TimeUnit unit) {
		return retryInfo.getDelay(unit);
	}

	public RetryInfo getRetryInfo() {
		return retryInfo;
	}

	public void setRetryInfo(RetryInfo retryInfo) {
		this.retryInfo = retryInfo;
	}
	
	public String retryInfoString(){
		if(retryInfo==null)
			return String.format("bufId【%s】 routerName【%s】 handlerName【%s】 无retryInfo", getBuf().getId(),router.getRouterName(),name());
		else
			return String.format("bufId【%s】 routerName【%s】 handlerName【%s】  msgId【%s】 间隔【%s】ms后重试第【%s】次,最大重试【%s】次",
			getBuf().getId(),router.getRouterName(),name(),
			retryInfo.getMsgId(), retryInfo.getInterval(),
			retryInfo.getRetryTimes(), retryInfo.getMaxRetryTimes());
	}
}
